TITL DAI FIRMWARE 3EC45-3EDF8 V1.1 ORG :EC45 * * * ********************** * COMPARE DE WITH HL * ********************** * * Exit: AF corrupted, BCDEHL preserved. * HL > DE : A=-1, CY=1, Z=0, S=1. * HL = DE : A= 0, CY=0, Z=1, S=0. * HL < DE : A= 1, CY=0, Z=0, S=0. * L3E194 MOV A,E SUB L MOV A,D SBB H SBB A RM If HL>DE: A=1, S=1 MOV A,E XRA L PUSH D MOV E,A MOV A,D XRA H ORA E POP D STC RZ If HL=DE: A=0, Z=CY=1 XRA A INR A RET If HL DE : CY=0. * New HL = DE : Z=1. * New HL < DE : CY=1. * L3E195 DCX H MOV A,H ANA L ADI :01 RC Ready if old HL was 0 MOV A,L ) SUB E ) Compare HL - DE MOV A,H ) SBB D ) RET * ************************* * RESTORE CPU REGISTERS * ************************* * * Restores CPU registers AFBCDEHL and PC. * Continues at PC address. * Stackpointer, TICC and GIC are not restored ! * L3E196 CALL :EDE7 Exchange bytes in reg. REM save area L3E197 LHLD :0053 Get stored PSW PUSH H POP PSW Restore PSW LHLD :0055 MOV B,H MOV C,L Restore BC LHLD :0057 XCHG Restore DE LHLD :005D PUSH H Addr next instr on stack LHLD :0059 Restore HL RET Goto addr in (005D/E) * ********************* * CALCULATE DE - HL * ********************* * * Exit: HL = DE - HL. * BCDE preserved, AF corrupted. * L3E198 MOV A,E SUB L MOV L,A L=E-L MOV A,D SBB H MOV H,A H=D-H-CY RET * ************ * M - MOVE * ************ * * Moves a block of data (laddr - haddr) given to * a given destination address (daddr). * * Exit: BC: 1st unused destination address. * DE: Last source address for direction of * movement. * HL: 1st unused source address. * AF: Corrupted. * MOVEK MVI C,:03 Nr of addr allowed CALL :EADE Get addr on stack DCR C 3 addr given ? JP :EA62 Error if not POP B daddr in BC POP D haddr in DE POP H laddr in HL PUSH H Save laddr on stack CALL :EC7C Calc length of block to REM be moved JC :EA62 Error if wrong inputs XTHL laddr in HL, length on stack MOV A,C ) SUB L ) Check if daddr < laddr MOV A,B ) SBB H ) JC :ECAE Then jump REM * If daddr > laddr: REM XTHL length in HL, laddr on stack DAD B daddr of highest byte MOV B,H ) Store it in BC MOV C,L ) POP H laddr in HL XCHG DE: laddr, HL: haddr L3E200 MOV A,M Get byte to be moved STAX B Move it DCX B Decr pntr daddr CALL :EC58 Check if ready RC Then quit JMP :ECA4 Next byte REM * If daddr < laddr: REM L3E201 XTHL Length in HL, laddr on stack POP H laddr in HL L3E202 MOV A,M Get byte STAX B And move it INX B Incr pntr daddr CALL :ED80 INX H; check if ready RC Then quit JMP :ECB0 Next byte * ************* * Z - RESET * ************* * * Z1: Reset CPU save area 0051-005E. Initialise * stackpointer to F900 and save it in 005B/C. * * Z2: Sets: current interrupt mask (005F) = #C5, * TICC control word (0060) = #FC, * GIC control word (0061) = #1B. * Initialises interrupt vector area #0062-#0071. * Sets interrupt vector RST 0 to #EB5D. * * Z3: Z1 + Z2. * * Exit: All registers corrupted. * ZEROK MVI C,:01 Nr of databytes allowed CALL :EADE Get hexnr and store it REM on stack POP H Get hexnr from stack MOV A,L into A PUSH PSW Save it again ANI :02 JZ :ECE9 Jump if Z1 only REM * If Z2 or Z3: REM MVI A,:C5 Set interrupt mask for REM clock, keyb, ext, timer 1 STA :005F Preserve int.mask MVI A,:F4 NOP NOP NOP ORI :08 LXI H,:0060 MOV M,A Set TICC contr.word = FC INX H MVI M,:1B Set GIC contr.word = 1B CALL :D91E Init int.vector addr LXI H,:EB5D SHLD :0062 Set RST0 vector = EB5D NOP NOP NOP NOP NOP L3E204 NOP ZERO1 POP PSW Get nr Z instr back RAR Check for Z2 only RNC Ready if Z2 only REM * If Z1 or Z3: REM MVI C,:00 ) LXI D,:005E ) Init reg. save area: LXI H,:0051 ) CALL :ED54 ) Fill (0051-005E) with 00 LXI H,:F900 SPHL Set SP=F900 SHLD :005B Save SP JMP :EA42 Return for new inputs * *************** * PRINT SPACE * *************** * * Exit: AFC corrupted, BDEHL preserved. * *TSP LSP MVI C,:20 JMP :EEB4 Print space * ********************************** * SCAN KEYBOARD, PRINT CHARACTER * ********************************** * * Gets a keyboard input. Zeroes are ignored. * The character is printed (if not 'ESC'). * * Exit: A : Character typed in. * Other registers preserved. * CIE CALL :EEB8 Scan keyboard ANI :7F Skip bit 7 JZ :ED06 Ignore zeroes (await an REM input) CPI :12 'ESC' ? PUSH B MOV C,A Char in C CNZ :EEB4 Print char if not 'ESC' MOV A,C Char in A POP B RET * * ************************** * PRINT ADDRESS IN ASCII * ************************** * * LADDR: An address in HL is converted to ASCII and * printed (4 nibbles). * LBYTE: A 1-byte value is printed in ASCII. * * Entry: LADDR: Address in HL. * LBYTE: Value in A. * Exit: AFC corrupted, BDEHL preserved. * LADDR MOV A,H Hibyte in A. CALL :ED1D Print both nibbles in ASCII MOV A,L Lobyte in A LBYTE PUSH PSW Preserve hex value 2 char RLC ) RLC ) Move hinibble RLC ) into lonibble RLC ) CALL :ED26 Print lonibble POP PSW Restore byte L3E210 ANI :0F Lonibble only CALL :ED40 Convert it to ASCII MOV C,A And store it in C JMP :EEB4 Print char in C * **************** * PRINT STRING * **************** * * Entry: HL points to string. End of string is 00. * Exit: HL points to 00 at end of string. * AFC corrupted, BDE preserved. * L3E211 MOV A,M Get byte from string MOV C,A into C ORA A Byte = 00 ? RZ Then ready CALL :EEB4 Print char in C INX H Pnts to next char JMP :ED2F Print next char * ************************* * PRINT CARRIAGE RETURN * ************************* * * Exit: AFC corrupted, BDEHL preserved. * LCRLF MVI C,:0D CALL :EEB4 Print 'CR' RET * ******************************* * CONVERT HEX NIBBLE TO ASCII * ******************************* * * Entry: Hex value in A. * Exit: ASCII value in A. * BCDEHL preserved. F corrupted. * L3E213 ADI :30 Convert CPI :3A Number 0-9? RC Then ready ADI :07 Convert A-F RET * ************ * F - FILL * ************ * * Fills a memory area between given boundaries * with given data. * * Exit: CY=1. All registers corrupted. * FILLK MVI C,:03 Nr of addr/data allowed CALL :EADE Get addr/data on stack DCR C 3 blocks given? JP :EA62 Error if not POP B Data in C POP D haddr in DE POP H laddr in HL FILL MOV M,C Data into memory CALL :ED80 INX H; check if ready RC Then quit JMP :ED54 Fill next addr * ****************** * S - SUBSTITUTE * ****************** * SUBSK MVI C,:01 Nr of addr allowed CALL :EADE Get addr on stack POP H Addr in HL MOV A,M Get contents of addr CALL :ED1D Print it in ASCII XRA A CALL :EE6A Evt. modify contents JNC :ED62 Next addr RET * *************** * X - EXAMINE * *************** * EXAMK LXI H,:EE9D Startaddr register table LXI D,:0053 Startaddr CPU save area JMP :EE39 Go to display routine * ********************** * V - VECTOR EXAMINE * ********************** * VECXK LXI H,:EEA8 Startaddr vector table LXI D,:005F Startaddr vector area JMP :EE39 Go to display routine * ************************************ * INCREMENT HL AND COMPARE WITH DE * ************************************ * * Exit: HL was FFFF: CY=1, Z=1. * Else: New HL < DE : CY=0. * New HL = DE : Z=1. * New HL > DE : CY=1. * BCDE preserved, HL=HL+1, AF corrupted. * INXCK INX H STC CY=1 MOV A,H ORA L RZ Abort if new HL is 0000 MOV A,E SUB L MOV A,D SBB H RET * ********** * G - GO * ********** * * Reads one field if given. * If no field given: Restores CPU registers, goes * to PC address. Returnaddress is #EA42 (into * command loop). * If field given: Saves it as PC, initialises TICC * and GIC. Returnaddress is #EA04. Goes to the * given address. * REMARK: The stackpointer is never restored ! * GOK MVI C,:01 CALL :EB07 Scan keyb; addr on stack DCR C No addr given? PUSH PSW CZ :EB56 Then check if 'CR' POP PSW JZ :EC63 No addr: restore CPU reg REM (but not SP/TICC/GIC !) and REM go to addr in 005D/E POP H 'GO' addr in HL SHLD :005D Save it L3E221 LHLD :0060 Get GIC/TICC init values MOV A,H GIC init value in A CALL :EDD5 Init GIC MOV A,L TICC init value in A CALL :EDB7 Init TICC LDA :005F Get current int mask STA :FFF8 Set int mask CALL :EDE7 exch. bytes in 0051-5E LXI H,:EA04 Returnaddr for 'GO' PUSH H Save EA04 on stack JMP :EC66 Restore CPU reg and 'GO' * * INITIALISE TICC: * * Entry: A: Initial value TICC command word (#FC). * Exit: AFBC corrupted, DEHL preserved. * L3E222 MOV B,A Init.value in B RLC A=F9 PUSH PSW On stack: A=F9, CY=1 RLC A=F3 RLC A=E7 RLC A=CF ANI :07 A=07 MOV C,A C=07 XRA A A=0 STC CY=1 L3E223 RAL ) On exit: A=80, DCR C ) C=FF, CY=0 JP :EDC2 ) MOV C,A C=80 POP PSW A=F9, CY=1 MOV A,C A=80 RAR A=C0 STA :FFF5 Set comm.rate reg for 9600 REM baud, 1 stop bit MOV A,B A=FC ANI :0F A=0C STA :FFF4 Set cmd reg for IN7, INTA REM enable RET * * INITIALISE GIC: * * This initialisation cancels the initial setting * done during 'power-on' by 3EF90. Only used during * 'GO'. * There seems to be some bug in the routine. All * ports are set to input, and then data is written * into one of this ports (PB - FE01). The function * of L3E225 is nonsense (?!). * * Entry: A: Initial value GIC command word (#1B). * Exit: AFBC corrupted, DEHL preserved. * L3E224 PUSH PSW Init value on stack, CY=0 LXI B,:FE03 Addr command word ORI :80 A=9B STAX B Set all ports to input DCR C BC=FE02 POP PSW A=1B, CY=0 RLC A=36, CY=0 SBB A A=0 L3E225 DCX B BC=FE01 STAX B (FE01)=00 (?!) DCR C BC=FE00 JP :EDE0 Writes 00 in non-existing REM address FDFE (?!) RET * **************************************** * EXCHANGE BYTES IN REGISTER SAVE AREA * **************************************** * * The hibytes and the lobytes of the addresses * 0053/0054 thru 0059/5A are exchanged which * each other. * * Exit: AFBCHL corrupted. DE preserved. * L3E238 LXI H,:0053 Startaddr MVI A,:04 Nr of addr to be exchanged L3E226 MOV B,M 1st byte in B INX H Pnts to next location MOV C,M 2nd byte in C MOV M,B 1st byte in 2nd location DCX H MOV M,C 2nd byte in 1st location INX H INX H Points to next addr DCR A Update counter JNZ :EDEC Next addr if not ready RET * * * UNL TSP EQU LSP LST END